package me.tomato3017.plugins.epicmusic;

import java.util.HashSet;
import java.util.Set;
import me.tomato3017.plugins.epicmusic.audio.AudioManager;
import me.tomato3017.plugins.epicmusic.commands.EpicMusicMainCE;
import me.tomato3017.plugins.epicmusic.commands.EpicMusicToggleCE;
import me.tomato3017.plugins.epicmusic.config.ConfigManager;
import me.tomato3017.plugins.epicmusic.region.RegionManager;
import me.tomato3017.plugins.epicmusic.thread.ThreadManager;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.Event.Priority;
import org.bukkit.event.Event.Type;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;


public class EpicMusic extends JavaPlugin {
    private final static String logPrefix = "[EpicMusic]";
  
    //Managers
    private static ConfigManager cManager;
    private static RegionManager rManager;
    private static AudioManager aManager;
    private static ThreadManager tManager;

    //Listeners
    private static EpicMusicPlayerListener pListener;
    private static EpicMusicSpoutListener sListener;
    private static EpicMusicAudioListener aListener;
    
    //Misc
    private static Set<Player> disabledPlayers;

    public static int getTimeBetween() {
        return cManager.getTimeBetween();
    }
    
    public void onDisable() {
        // TODO: Create reinit routines
        
        //Save the config again
        cManager.saveConfig();
        
        //NULL ALL THE OBJECTS!!!
        cManager = null;
        rManager = null;
        aManager = null;
        tManager = null;
        pListener = null;
        sListener = null;
        aListener = null;
        
        getServer().getScheduler().cancelTasks(this);
        log(this.toString() + " is now disabled!");
    }

    public void onEnable() {
        log("Loading " + this.toString());
        PluginManager pm = getServer().getPluginManager();
        
        Plugin spout = pm.getPlugin("Spout");
        
        if(spout == null){
            log("Spout NOT detected. Disabling!");
            this.setEnabled(false);
            return;
        }
        
        //Load the config
        rManager = new RegionManager(this);
        aManager = new AudioManager(this);
        tManager = new ThreadManager(this);
        cManager = new ConfigManager(this);
        getConfigManager().loadConfig();
        
        //Listener init
        pListener = new EpicMusicPlayerListener(this);
        sListener = new EpicMusicSpoutListener(this);
        aListener = new EpicMusicAudioListener(this);
        
        //Init disabled players
        disabledPlayers = new HashSet<Player>();
        
        //Hooks
        getServer().getPluginManager().registerEvent(Type.CUSTOM_EVENT, sListener, Priority.Normal, this);
        getServer().getPluginManager().registerEvent(Type.PLAYER_MOVE, pListener, Priority.Monitor, this);
        getServer().getPluginManager().registerEvent(Type.PLAYER_QUIT, pListener, Priority.Normal, this);
        getServer().getPluginManager().registerEvent(Type.PLAYER_TELEPORT, pListener, Priority.Low, this);
        getServer().getPluginManager().registerEvent(Type.CUSTOM_EVENT, aListener, Priority.Normal, this);
        
        //Command Executors
        
        //EpicMusicToggle
        EpicMusicToggleCE epToggle = new EpicMusicToggleCE(this);
        getServer().getPluginCommand("epicmusictoggle").setExecutor(epToggle);
        
        EpicMusicMainCE epMain = new EpicMusicMainCE(this);
        getServer().getPluginCommand("epicmusic").setExecutor(epMain);
        
        log(this + " is now enabled!");
        
    }

    
    public static void log(String text){
        System.out.println(logPrefix + " " + text);
    }
    
    public static void debugLog(String text){
        if(!isDEBUG())
            return;
        
        log("-DEBUG-" + text);
    }
    
    public static void debugLog(String text, int debugLevel){
        if(!isDEBUG() || (debugLevel >= getDebugLevel()))
            return;
        
        log("-DEBUG-" + text);      
    }
    
    public void Disable(){
        this.setEnabled(false);
    }
    
    public void Enable(){
        this.setEnabled(true);
    }
    
    
    public static void sendPlayerMessage(Player player, String text){
        if(player instanceof  Player && player.isOnline()){
            player.sendMessage(ChatColor.GOLD + logPrefix + ChatColor.WHITE + " " + text);
        }
    }

    public static boolean isDEBUG() {
        return getConfigManager().isDEBUG();
    }

    /**
     * @return the cManager
     */
    public static ConfigManager getConfigManager() {
        return cManager;
    }

    public static RegionManager getRegionManager() {
        return rManager;
    }
    
    public static AudioManager getAudioManager() {
        return aManager;
    }

    public static ThreadManager getThreadManager() {
        return tManager;
    }
    
    public static int getDefaultSongLength(){
        return cManager.getDefaultSongLength();
    }


    public static int getDebugLevel() {
        return cManager.getDebugLevel();
    }

    public static int getDefaultSoundEffectDistance() {
        return cManager.getMinSoundEffectDistance();
    }

    @Override
    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
        if(sender instanceof Player){
            Player player = (Player) sender;
            if(command.getName().equals("epicmusictoggle")){
                if(disabledPlayers.contains(player)){
                    EpicMusic.sendPlayerMessage(player, "Enabling EpicMusic!");
                    disabledPlayers.remove(player);
                }
                else{
                    EpicMusic.sendPlayerMessage(player, "Disabling EpicMusic!");
                    disabledPlayers.add(player);
                    aManager.stopMusic(player);
                }
                
                return true;
            }
        }
        
        return false;
    }
    
    public static boolean isPlayerDisabled(Player player){
        if(player instanceof Player){
            return disabledPlayers.contains(player);
        }
        
        return false;
    }
    
    public static boolean disablePlayer(Player player){
        if(player instanceof Player){
            disabledPlayers.add(player);
            return true;
        }
        
        return false;
    }
    
    public static boolean enablePlayer(Player player){
        if(player instanceof Player){
            return disabledPlayers.remove(player);
        }
        
        return false;
    }
}
